#include "netdisk.h"

int socket_client(char* ip,char* port){
    int fd;
    struct sockaddr_in  client_addr;
    fd=socket(AF_INET,SOCK_STREAM,0);
    //对端口进行初步设置
    memset(&client_addr,0,sizeof(client_addr));
    client_addr.sin_family=AF_INET;
    client_addr.sin_port=htons(atoi(port));
    client_addr.sin_addr.s_addr=inet_addr(ip);
    int reuse=1;
    int ret;
    // 进行连接设置
    ret=setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(void*)&reuse,sizeof(int));
    ERROR_CHECK(ret,-1,"setsockopt")
    ret=connect(fd,(struct sockaddr*)&client_addr,sizeof(struct sockaddr));
    ERROR_CHECK(ret,-1,"connect")
    return fd;
}

void client_handle(int fd)
{
    train_t train;
	char cmd[128];
    bzero(cmd,sizeof(cmd));
	while(read(STDIN_FILENO,cmd,sizeof(cmd)))//从标准输入中读取命令到cmd缓冲中
	{
		train.data_len=strlen(cmd);
		//printf("%s\n",cmd);
		send(fd,&(train.data_len),sizeof(int), 0);//发命令长度给服务器端
		//printf("client data_len=%d\n",train.data_len);
		//sendn(fd,cmd,train.data_len);//发送命令给服务器
		send(fd,cmd,train.data_len,0);
		if(strncmp("cd",cmd,2)==0)
		{
			system("clear");
			//printf("this is client cd\n");
            memset(&train,0,sizeof(train));
			recv(fd,&train.data_len,sizeof(int),0);//接cd之后的路径
			recvn(fd,train.buf,train.data_len);
			printf("%s\n", train.buf);
		}else if(strncmp("ls",cmd,2)==0)
		{
			system("clear");
            memset(&train,0,sizeof(train));
			while(1)
			{
				recv(fd,&train.data_len,sizeof(int),0);//接文件信息
				if(train.data_len==0)
				{
					break ;
				}
				recvn(fd,train.buf,train.data_len);
				printf("%s\n",train.buf);
			}
		}else if(strncmp("puts",cmd,4)==0)//明天继续
		{
			char file_name[256];
			int file_pos=5 ;
			bzero(file_name,sizeof(file_name));
			while(sscanf(cmd+file_pos,"%s",file_name)==1)
			{
				file_pos+=strlen(file_name)+1; 
				if(upload(fd, file_name)==0)
				{
					printf("file-> %s upload success\n",file_name);
				}else 
				{
					printf("file-> %s upload failed\n",file_name);
				}
				
			}
		}else if(strncmp("gets",cmd,4)==0)
		{
			char file_name[256];
			int file_pos =5;
			bzero(file_name,sizeof(file_name));
			while(sscanf(cmd+file_pos,"%s",file_name)==1)
			{
				file_pos+=strlen(file_name)+1 ;
				if(download(fd,file_name)==0)
				{
					printf("file -> %s download success \n",file_name);
				}else
				{
					printf("file -> %s download failed \n",file_name);
				}
			}	
		}
		else if(strncmp("remove",cmd,6)==0)
		{
			system("clear");
            memset(&train,0,sizeof(train));
			recv(fd,&train.data_len,sizeof(int),0);
			recvn(fd,train.buf,train.data_len);
			printf("%s\n", train.buf);
			
		}else if(strncmp("pwd",cmd,3)==0)
		{
			system("clear");
			memset(&train,0,sizeof(train));
			recv(fd,&train.data_len,sizeof(int),0);//接cd之后的路径
			recvn(fd,train.buf,train.data_len);
			printf("%s\n", train.buf);
		}else 
		{
			printf("wrong cmd!\n");
			continue ;
		}
		memset(cmd,0,sizeof(cmd));
    }
}

int recvn(int fd_recv,char* recv_buf,int len)
{
	int sum=0;
	int received=0;
	while(sum<len)
	{
		received=recv(fd_recv,&recv_buf[sum],len-sum,0);
		sum+=received ;
	}
	recv_buf[sum]='\0';
	return sum;
}

int sendn(int fd_send,char* send_buf,int len)
{
	int sum=0 ;
	//printf("send_buf=%s\n",send_buf);
	int sended;
	while(sum<len)
	{
		sended=send(fd_send,send_buf+sum,len-sum,0);
		sum+=sended ;
	}
	return sum ;
}

int upload(int fd_up,char* file_name)
{
	int fd_file=open(file_name,O_RDONLY);
	ERROR_CHECK(fd_file,-1,"open")
	char *read_buf=(char*)malloc(Num);
	bzero(read_buf,sizeof(read_buf));
	int readed;
	while(1)
	{
		readed=readn(fd_file,read_buf,Num);//读文件到read_buf中并返回读取的字节数
		if(readed <Num)//文件的最后一部分
		{
			send(fd_up,&readed,sizeof(int),0);
			sendn(fd_up,read_buf,readed);
			break ;
		}else
		{
			send(fd_up,&readed,sizeof(int),0);
			sendn(fd_up,read_buf,readed);
		}
	}
	int flag=0;
	send(fd_up,&flag,sizeof(flag),0);
	close(fd_file);
	return 0 ;
}
//接收文件
int download(int fd_down,char* file_name)
{
	int fd_file=open(file_name, O_WRONLY|O_CREAT,0666 );
	ERROR_CHECK(fd_file,-1,"open")
	char* write_buf=(char*)malloc(Num);
	bzero(write_buf,sizeof(write_buf));
	int writed;
	while(1)
	{
		recv(fd_down,&writed,sizeof(int),0);
		if(writed==0)
		{
			break ;
		}
		recvn(fd_down,write_buf,writed);
		writen(fd_file,write_buf,writed);
	}
	close(fd_file);
	return 0 ;
}
int readn(int fd_read,char* read_buf,int len)
{
	int sum=0 ;
	int readed ;
	while(sum<len)//一直读文件，直至把read_buf读满
	{
		readed=read(fd_read,&read_buf[sum],len-sum);
		if(readed==0)
		{
			break ;
		}
		sum+=readed ;
	}
	return sum ;		
}

int writen(int fd_write,char* write_buf,int len)
{
	int sum=0;
	int writed;
	while(sum<len)
	{
		writed=write(fd_write,write_buf+sum,len-sum);
		sum+=writed;
	}
	return sum ;
}
